﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Security.Claims;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using Newtonsoft.Json;
using NLog;
using Org.BouncyCastle.X509;
using SealManagement.Common;
using SealManagement.Extensions;
using SealManagement.Models;
using SealManagement.SqlData;

namespace SealManagement.Controllers
{

    [Authorize(Roles = "User")]
    public class UserController : Controller
    {
        private readonly IMemoryCache _memoryCache;
        private SignContext _context;
        private static Logger logger = LogManager.GetCurrentClassLogger();
        public UserController(SignContext context, IMemoryCache memoryCache)
        {
            _context = context;
            _memoryCache = memoryCache;
        }
        // <summary>
        // 显示用户列表
        // </summary>
        // <returns>返回用户列表界面</returns>
        public async Task<IActionResult> Index()
        {
            //var total = await _context.Users.CountAsync();
            var guid = Guid.NewGuid();
            ViewData["ValidateCode"] = guid.ToString();
            HttpContext.Response.Cookies.Append("ValidateCode",
                Convert.ToBase64String(ToolClass.Encrypt(Encoding.UTF8.GetBytes(guid.ToString()))));
            return View();
        }
        [HttpPost]
        public async Task<IActionResult> Index(int PageSize = 10, int PageIndex = 1)
        {
            X509CertificateParser certificateParser = new X509CertificateParser();

            var users = await _context.Users.Where(p => p.IsDelete == 0).Skip(PageSize * (PageIndex - 1)).Take(PageSize).ToListAsync() ?? null;
            var data = users.Select(s =>
            {
                //微软自带X509Certificate不认同项目中UKey，需要转为Org.BouncyCastle.X509.X509Certificate类型
                Org.BouncyCastle.X509.X509Certificate cert =
                certificateParser.ReadCertificate(Convert.FromBase64String(s.Certificator));
                return new UserInfo()
                {
                    User = s,
                    Issuer = cert.IssuerDN.ToString(),
                    Subject = cert.SubjectDN.ToString(),
                    NotBefore = cert.NotBefore.ToString("yyyy-MM-dd HH:mm:ss"),
                    NotAfter = cert.NotAfter.ToString("yyyy-MM-dd HH:mm:ss"),
                };
            });
            var total = await _context.Users.Where(p => p.IsDelete == 0).CountAsync();
            return Json(new { state = resultType.Success, data = data, total = total });
        }
        /// <summary>
        /// 显示单个用户详细信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<IActionResult> Detail(string EncryptData)
        {
            if (!Define.IsChecked)
            {
                return Json(new { state = resultType.Error, message = "系统未经自检，请先执行自检后操作" });
            }
            var jsonBack = ToolClass.EncryptTransit(EncryptData);
            //if (string.IsNullOrEmpty(jsonBack))
            //{
            //    return Json(new { state = resultType.Error, message = "参数错误" });
            //}
            if (int.TryParse(jsonBack, out var errorCodeValue))
            {
                var errorCode = (ErrorCode)errorCodeValue;
                return Json(new { state = resultType.Error, message = $"错误码：{errorCodeValue}，错误信息：{ToolClass.GetDescription(errorCode)}" });
            }
            var EditModel = JsonConvert.DeserializeObject<EditModel>(jsonBack);
            if (EditModel == null)
            {
                return Json(new { state = resultType.Error, message = "数据不存在" });
            }
            var user = await _context.Users.Where(u => u.Id == EditModel.Id).FirstAsync();
            X509CertificateParser certificateParser = new X509CertificateParser();
            Org.BouncyCastle.X509.X509Certificate cert =
                    certificateParser.ReadCertificate(Convert.FromBase64String(user.Certificator));
            var data = new UserInfo()
            {
                User = user,
                Issuer = cert.IssuerDN.ToString(),
                Subject = cert.SubjectDN.ToString(),
                NotBefore = cert.NotBefore.ToString("yyyy-MM-dd HH:mm:ss"),
                NotAfter = cert.NotAfter.ToString("yyyy-MM-dd HH:mm:ss"),
            };
            //return View(user);
            _memoryCache.Set("UserModelForUserDetail", data);
            return Json(new { state = resultType.Success, data = data });
        }

        public async Task<IActionResult> DetailForViewShow()
        {
            return View("Detail", _memoryCache.Get("UserModelForUserDetail") as UserInfo);
        }
        // 重构用
        //public async Task<IActionResult> Details(int id)
        //{
        //    var user = await _context.Users.Where(u => u.Id == id).FirstAsync();
        //    return Json(new { state = resultType.Success, data = user }); 
        //}
        /// <summary>
        /// 创建一个新用户
        /// </summary>
        /// <returns></returns>
        public IActionResult Create()
        {
            var guid = Guid.NewGuid();
            ViewData["ValidateCode"] = guid.ToString();
            HttpContext.Response.Cookies.Append("ValidateCode",
                Convert.ToBase64String(ToolClass.Encrypt(Encoding.UTF8.GetBytes(guid.ToString()))));
            return View();
        }

        /// <summary>
        /// 创建一个新用户
        /// </summary>
        /// <param name="UserModel"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> Create(string EncryptData)
        {
            if (!Define.IsChecked)
            {
                return Json(new { state = resultType.Error, message = "系统未经自检，请先执行自检后操作" });
            }
            var jsonBack = ToolClass.EncryptTransit(EncryptData);
            //if (string.IsNullOrEmpty(jsonBack))
            //{
            //    return Json(new { state = resultType.Error, message = "参数错误" });
            //}
            if (int.TryParse(jsonBack, out var errorCodeValue))
            {
                var errorCode = (ErrorCode)errorCodeValue;
                return Json(new { state = resultType.Error, message = $"错误码：{errorCodeValue}，错误信息：{ToolClass.GetDescription(errorCode)}" });
            }
            var userViewModel = JsonConvert.DeserializeObject<UserViewModel>(jsonBack);
            if (userViewModel == null)
            {
                return Json(new { state = resultType.Error, message = "数据不存在" });
            }
            #region cookie验证
            var guidStr = "";
            if (!HttpContext.Request.Cookies.TryGetValue("ValidateCode", out guidStr))
            {
                return Json(new { state = resultType.Error, message = "cookie未设置，请联系管理员" });
            }
            var guidFromCookie = Encoding.UTF8.GetString(ToolClass.Decrypt(Convert.FromBase64String(guidStr)));
            if (!string.Equals(guidFromCookie, userViewModel.ValidateCode, StringComparison.OrdinalIgnoreCase))
            {
                return Json(new { state = resultType.Error, message = "cookie不正确，请刷新页面后重试" });
            }
            #endregion
            var UserModel = userViewModel.User;
            var arrayno = UserModel.ArrayNo;
            var user = _context.Users.Count() == 0 ? null : await _context.Users.FirstOrDefaultAsync(p => p.ArrayNo == arrayno && p.IsDelete == 0);
            if (user != null)
            {
                return Json(new
                {
                    state = resultType.Error,
                    message = "已存在当前证书",
                    data = user
                });
            }
            var signmaker = _context.SignMakers.Count() == 0 ? null : await _context.SignMakers.FirstOrDefaultAsync(p => p.ArrayNo == arrayno && p.IsDelete == 0);
            if (signmaker != null)
            {
                return Json(new
                {
                    state = resultType.Error,
                    message = "已存在当前证书",
                    data = signmaker
                });
            }
            var datetimeStr = DateTime.Now.ToString();
            var userNew = new User()
            {
                UserName = UserModel.UserName,
                ArrayNo = UserModel.ArrayNo,
                Certificator = UserModel.Certificator,
                CreateDate = datetimeStr,
                Remark = UserModel.Remark ?? "",
                IsDelete = 0
            };
            _context.Users.Add(userNew);
            var res = await _context.SaveChangesAsync();
            if (res > 0)
            {
                logger.Info($"{User.Identity.Name}创建了新用户{UserModel.UserName}");
                _context.InfoLogs.Add(new InfoLog()
                {
                    UserId = Convert.ToInt32(User.FindFirst(ClaimTypes.Sid).Value),
                    UserName = User.Identity.Name,
                    CreateDate = DateTime.Now.ToString(),
                    UserType = (int)userType.User,
                    Remark = $"{User.Identity.Name}创建了新用户{UserModel.UserName}",
                    ManageType = manageType.AddUser.ToString()
                });
            }
            _context.SaveChanges();
            return Json(new { state = resultType.Success, data = UserModel });
        }

        /// <summary>
        /// 编辑用户信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<IActionResult> Edit(string EncryptData)
        {
            if (!Define.IsChecked)
            {
                return Json(new { state = resultType.Error, message = "系统未经自检，请先执行自检后操作" });
            }
            var jsonBack = ToolClass.EncryptTransit(EncryptData);
            //if (string.IsNullOrEmpty(jsonBack))
            //{
            //    return Json(new { state = resultType.Error, message = "参数错误" });
            //}
            if (int.TryParse(jsonBack, out var errorCodeValue))
            {
                var errorCode = (ErrorCode)errorCodeValue;
                return Json(new { state = resultType.Error, message = $"错误码：{errorCodeValue}，错误信息：{ToolClass.GetDescription(errorCode)}" });
            }
            var EditModel = JsonConvert.DeserializeObject<EditModel>(jsonBack);
            if (EditModel == null)
            {
                return Json(new { state = resultType.Error, message = "数据不存在" });
            }

            var user = await _context.Users.Where(u => u.Id == EditModel.Id).FirstAsync();
            _memoryCache.Set("UserModelForUserEdit", user);
            return Json(new { state = resultType.Success, data = user });
        }

        public async Task<IActionResult> EditForViewShow()
        {
            var guid = Guid.NewGuid();
            ViewData["ValidateCode"] = guid.ToString();
            HttpContext.Response.Cookies.Append("ValidateCode",
                Convert.ToBase64String(ToolClass.Encrypt(Encoding.UTF8.GetBytes(guid.ToString()))));
            return View("Edit", _memoryCache.Get("UserModelForUserEdit") as User);
        }

        // 重构用
        //public async Task<IActionResult> Edits(int id)
        //{
        //    var user = await _context.Users.Where(u => u.Id == id).FirstAsync();
        //    return Json(new { state = resultType.Success, data = user }); 
        //}
        /// <summary>
        /// 编辑用户信息
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> EditForUser(string EncryptData)
        {
            if (!Define.IsChecked)
            {
                return Json(new { state = resultType.Error, message = "系统未经自检，请先执行自检后操作" });
            }
            var jsonBack = ToolClass.EncryptTransit(EncryptData);
            //if (string.IsNullOrEmpty(jsonBack))
            //{
            //    return Json(new { state = resultType.Error, message = "参数错误" });
            //}
            if (int.TryParse(jsonBack, out var errorCodeValue))
            {
                var errorCode = (ErrorCode)errorCodeValue;
                return Json(new { state = resultType.Error, message = $"错误码：{errorCodeValue}，错误信息：{ToolClass.GetDescription(errorCode)}" });
            }
            var userViewModel = JsonConvert.DeserializeObject<UserViewModel>(jsonBack);
            if (userViewModel == null)
            {
                return Json(new { state = resultType.Error, message = "数据不存在" });
            }
            #region cookie验证
            var guidStr = "";
            if (!HttpContext.Request.Cookies.TryGetValue("ValidateCode", out guidStr))
            {
                return Json(new { state = resultType.Error, message = "cookie未设置，请联系管理员" });
            }
            var guidFromCookie = Encoding.UTF8.GetString(ToolClass.Decrypt(Convert.FromBase64String(guidStr)));
            if (!string.Equals(guidFromCookie, userViewModel.ValidateCode, StringComparison.OrdinalIgnoreCase))
            {
                return Json(new { state = resultType.Error, message = "cookie不正确，请刷新页面后重试" });
            }
            #endregion
            var user = userViewModel.User;
            var editUser = _context.Users.Single(p => p.Id == user.Id);
            var username = user.UserName == null ? "" : user.UserName.Trim();
            var remark = user.Remark == null ? "" : user.Remark.Trim();
            if (username == "" || remark == "")
                return Json(new { state = resultType.Error, message = "请将信息填写完整" });
            editUser.UserName = username;
            editUser.Remark = remark;
            _context.Update(editUser);
            int res = await _context.SaveChangesAsync();
            if (res > 0)
            {
                logger.Info($"{User.Identity.Name}编辑了用户{user.UserName}的信息");
                _context.InfoLogs.Add(new InfoLog()
                {
                    UserId = Convert.ToInt32(User.FindFirst(ClaimTypes.Sid).Value),
                    UserName = User.Identity.Name,
                    CreateDate = DateTime.Now.ToString(),
                    UserType = (int)userType.User,
                    Remark = $"{User.Identity.Name}编辑了用户{user.UserName}的信息",
                    ManageType = manageType.EditUser.ToString()
                });
            }
            _context.SaveChanges();
            return Json(new { state = resultType.Success, data = user });
        }

        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<IActionResult> Delete(string EncryptData)
        {
            if (!Define.IsChecked)
            {
                return Json(new { state = resultType.Error, message = "系统未经自检，请先执行自检后操作" });
            }
            var jsonBack = ToolClass.EncryptTransit(EncryptData);
            //if (string.IsNullOrEmpty(jsonBack))
            //{
            //    return Json(new { state = resultType.Error, message = "参数错误" });
            //}
            if (int.TryParse(jsonBack, out var errorCodeValue))
            {
                var errorCode = (ErrorCode)errorCodeValue;
                return Json(new { state = resultType.Error, message = $"错误码：{errorCodeValue}，错误信息：{ToolClass.GetDescription(errorCode)}" });
            }
            var EditModel = JsonConvert.DeserializeObject<EditModel>(jsonBack);
            if (EditModel == null)
            {
                return Json(new { state = resultType.Error, message = "数据不存在" });
            }
            #region cookie验证
            var guidStr = "";
            if (!HttpContext.Request.Cookies.TryGetValue("ValidateCode", out guidStr))
            {
                return Json(new { state = resultType.Error, message = "cookie未设置，请联系管理员" });
            }
            var guidFromCookie = Encoding.UTF8.GetString(ToolClass.Decrypt(Convert.FromBase64String(guidStr)));
            if (!string.Equals(guidFromCookie, EditModel.ValidateCode, StringComparison.OrdinalIgnoreCase))
            {
                return Json(new { state = resultType.Error, message = "cookie不正确，请刷新页面后重试" });
            }
            #endregion
            var user = _context.Users.Where(u => u.Id == EditModel.Id).First();
            if (user.UserName == User.Identity.Name)
                return Json(new { state = resultType.Error, message = "不能删除当前管理员" });
            _context.Remove(user);
            int res = await _context.SaveChangesAsync();
            if (res > 0)
            {
                logger.Info($"{User.Identity.Name}删除了用户{user.UserName}的信息");
                _context.InfoLogs.Add(new InfoLog()
                {
                    UserId = Convert.ToInt32(User.FindFirst(ClaimTypes.Sid).Value),
                    UserName = User.Identity.Name,
                    CreateDate = DateTime.Now.ToString(),
                    UserType = (int)userType.User,
                    Remark = $"{User.Identity.Name}删除了用户{user.UserName}的信息",
                    ManageType = manageType.DelUser.ToString()
                });
            }
            _context.SaveChanges();
            return Json(new { state = resultType.Success, message = "删除成功" });
        }

        public async Task<IActionResult> DownCert(string EncryptData)
        {
            if (!Define.IsChecked)
            {
                return Json(new { state = resultType.Error, message = "系统未经自检，请先执行自检后操作" });
            }
            //.cer文件
            var jsonBack = ToolClass.EncryptTransit(EncryptData);
            //if (string.IsNullOrEmpty(jsonBack))
            //{
            //    return Json(new { state = resultType.Error, message = "参数错误" });
            //}
            if (int.TryParse(jsonBack, out var errorCodeValue))
            {
                var errorCode = (ErrorCode)errorCodeValue;
                return Json(new { state = resultType.Error, message = $"错误码：{errorCodeValue}，错误信息：{ToolClass.GetDescription(errorCode)}" });
            }
            var editModel = JsonConvert.DeserializeObject<EditModel>(jsonBack);
            if (editModel == null)
            {
                return Json(new { state = resultType.Error, message = "数据不存在" });
            }
            var user = _context.Users.Single(p => p.Id == editModel.Id);
            var certBytes = Convert.FromBase64String(user.Certificator);
            logger.Info($"{User.Identity.Name}下载了证书");
            _context.InfoLogs.Add(new InfoLog()
            {
                UserId = Convert.ToInt32(User.FindFirst(ClaimTypes.Sid).Value),
                UserName = User.Identity.Name,
                CreateDate = DateTime.Now.ToString(),
                UserType = (int)userType.User,
                Remark = $"{User.Identity.Name}下载了证书",
                ManageType = manageType.DownLoadFile.ToString()
            });
            await _context.SaveChangesAsync();
            return File(certBytes, "text/plain", $"Cert_{user.Id}.cer");//文本mime
        }
    }
}